Home:ALL Converter>AES Encryption CryptLib in iOS 13 not working

AES Encryption CryptLib in iOS 13 not working

Ask Time:2019-09-25T20:56:12         Author:Abdul Nasir B A

Json Formatter

My application uses AES 256 encryption to encrypt a string. The same code that was used before is generating a different result. This problem started when iOS 13 was released. And it happens only to applications that are shipped to the store or built with Xcode 11.

Here is the code used for the encryption:


- (NSData *)encrypt:(NSData *)plainText key:(NSString *)key  iv:(NSString *)iv {  
    char keyPointer[kCCKeySizeAES256+2],// room for terminator (unused) ref: https://devforums.apple.com/message/876053#876053  
    ivPointer[kCCBlockSizeAES128+2];  
    BOOL patchNeeded;  
    bzero(keyPointer, sizeof(keyPointer)); // fill with zeroes for padding  

    patchNeeded= ([key length] > kCCKeySizeAES256+1);  
    if(patchNeeded)  
    {  
        NSLog(@"Key length is longer %lu", (unsigned long)[[self md5:key] length]);  
        key = [key substringToIndex:kCCKeySizeAES256]; // Ensure that the key isn't longer than what's needed (kCCKeySizeAES256)  
    }  

    //NSLog(@"md5 :%@", key);  
    [key getCString:keyPointer maxLength:sizeof(keyPointer) encoding:NSUTF8StringEncoding];  
    [iv getCString:ivPointer maxLength:sizeof(ivPointer) encoding:NSUTF8StringEncoding];  

    if (patchNeeded) {  
        keyPointer[0] = '\0';  // Previous iOS version than iOS7 set the first char to '\0' if the key was longer than kCCKeySizeAES256  
    }  

    NSUInteger dataLength = [plainText length];  

    //see https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/CCryptorCreateFromData.3cc.html  
    // For block ciphers, the output size will always be less than or equal to the input size plus the size of one block.  
    size_t buffSize = dataLength + kCCBlockSizeAES128;  
    void *buff = malloc(buffSize);  

    size_t numBytesEncrypted = 0;  
    //refer to http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/CommonCrypto/CommonCryptor.h  
    //for details on this function  
    //Stateless, one-shot encrypt or decrypt operation.  
    CCCryptorStatus status = CCCrypt(kCCEncrypt, /* kCCEncrypt, etc. */  
                                     kCCAlgorithmAES128, /* kCCAlgorithmAES128, etc. */  
                                     kCCOptionPKCS7Padding, /* kCCOptionPKCS7Padding, etc. */  
                                     keyPointer, kCCKeySizeAES256, /* key and its length */  
                                     ivPointer, /* initialization vector - use random IV everytime */  
                                     [plainText bytes], [plainText length], /* input  */  
                                     buff, buffSize,/* data RETURNED here */  
                                     &numBytesEncrypted);  
    if (status == kCCSuccess) {  
        return [NSData dataWithBytesNoCopy:buff length:numBytesEncrypted];  
    }  

    free(buff);  
    return nil;  
}  


- (NSString *) encryptPlainTextWith:(NSString *)plainText key:(NSString *)key iv:(NSString *)iv {  
    return [[[[CryptLib alloc] init] encrypt:[plainText dataUsingEncoding:NSUTF8StringEncoding] key:[[CryptLib alloc] sha256:key length:32] iv:iv] base64EncodedStringWithOptions:0];  
} 
/** 

* This function computes the SHA256 hash of input string 
* @param key input text whose SHA256 hash has to be computed 
* @param length length of the text to be returned 
* @return returns SHA256 hash of input text 
*/  
- (NSString*) sha256:(NSString *)key length:(NSInteger) length{  
    const char *s=[key cStringUsingEncoding:NSASCIIStringEncoding];  
    NSData *keyData=[NSData dataWithBytes:s length:strlen(s)];  

    uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0};  
    CC_SHA256(keyData.bytes, (CC_LONG)keyData.length, digest);  
    NSData *out=[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];  
    NSString *hash=[out description];  
    hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];  
    hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];  
    hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];  

    if(length > [hash length])  
    {  
        return  hash;  
    }  
    else  
    {  
        return [hash substringToIndex:length];  
    }  
}

##

I would like to know if something in the code path has changed in the way it works. The method called to do the encryptions is "encryptPlainTextWith". Thanks in advance.

Author:Abdul Nasir B A,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/58098958/aes-encryption-cryptlib-in-ios-13-not-working
Abdul Nasir B A :

Inside:\n\n- (NSString*) sha256:(NSString *)key length:(NSInteger) length\n\n\nI replaced\n\nNSString *hash=[out description];\n\n\nTo\n\nNSString *hash=[out debugDescription];\n\n\nAnd everything got back to normal. Cheers Happy coding.\n\nAlternative Solution as per @Rob Napier\n\ncreate separate function for converting NSData to Hex\n\n#pragma mark - String Conversion\n-(NSString*)hex:(NSData*)data{\n NSMutableData *result = [NSMutableData dataWithLength:2*data.length];\n unsigned const char* src = data.bytes;\n unsigned char* dst = result.mutableBytes;\n unsigned char t0, t1;\n\n for (int i = 0; i < data.length; i ++ ) {\n t0 = src[i] >> 4;\n t1 = src[i] & 0x0F;\n\n dst[i*2] = 48 + t0 + (t0 / 10) * 39;\n dst[i*2+1] = 48 + t1 + (t1 / 10) * 39;\n }\n\n return [[NSString alloc] initWithData:result encoding:NSASCIIStringEncoding];\n}\n\n\nAfter that Inside:\n\n- (NSString*) sha256:(NSString *)key length:(NSInteger) length\n\n\nI replaced\n\nNSString *hash=[out description];\n\n\nTo\n\nNSString *hash = [self hex:out];\n",
2019-09-26T08:22:06
yy